// RMSWaveSocket.h: interface for the CRMSWaveSocket class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_RMSWAVESOCKET_H__AB6D9EB2_1169_4EC5_901F_4655D93FA70E__INCLUDED_)
#define AFX_RMSWAVESOCKET_H__AB6D9EB2_1169_4EC5_901F_4655D93FA70E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "../Common/RMSThread.h"
#include "../Common/sfec.h"

#include <afxmt.h>

struct CUDPPacket
{
  int length;
  unsigned char data[1536];
  SOCKADDR_IN toaddr;
  CUDPPacket();
  CUDPPacket(unsigned char* pdata, int len, SOCKADDR_IN ip) : toaddr(ip) {Load(pdata, len);};
  void Load(unsigned char* pdata, int len) {
    length = min(len,sizeof(data));
    memcpy(data, pdata, length);
  }
};

class CTimedSending : public TheTimer
{
private:
  SOCKET sock;
  bool EmptyCall;
  queue<CUDPPacket> packets; int maxpackets;
  CRITICAL_SECTION cs;
  HANDLE hOutside;
public:
  CTimedSending(SOCKET udpsock, int interval, int maxqueue);
  virtual ~CTimedSending();
  void SetSocket(SOCKET udpsock) {EnterCriticalSection(&cs);sock = udpsock;LeaveCriticalSection(&cs);};

  virtual void Call();
  void AddData(unsigned char* pdata, int len, SOCKADDR_IN ip);
};

class CBaseServer;
class CRMSWaveSocket : public CRMSThread  
{
public:
	CBaseServer *pBaseServer;
	CRMSClientSocket* pClient;
           CSimpleFEC* pFEC;
           CTimedSending* pSending;

	CRMSWaveSocket(CBaseServer* p, CRMSClientSocket* pClient);
	virtual ~CRMSWaveSocket();

	int CameraID;

	int				*pSzAudio;
	BYTE			 *dtAudio;
	CRITICAL_SECTION *pCriticalAudio;

	BOOL	m_bVideo;
	BOOL	m_bAudio;

	int*				pSzVideo;
	BYTE*				dtVideo;
	CRITICAL_SECTION*	pCriticalData;

	DWORD	m_dwTypeVideo;
	DWORD	m_frames;

	CEvent	m_eventNewFrame;

// Members
	SOCKET m_udpSocket;

	BYTE	m_byID;
	DWORD	m_dwTypeAudio;
	long	StartTime;
	int		Samples;

	bool	m_bActive;
	bool	NewPassword;

	CEvent	m_eventNewWave;
// Methods
	int StartWaveSession(SOCKADDR_IN saServer, BOOL bAudio = TRUE, BOOL bVideo = FALSE);
	DWORD OnTerminate();
protected:
	DWORD ThreadFunc();

	SOCKADDR_IN m_saServer;
	SOCKADDR_IN m_saClient;

	BYTE*	m_pData;
private:
	void CloseSession();
	void ResetData();
};

typedef CRMSWaveSocket* LPRMSWaveSocket;

#endif // !defined(AFX_RMSWAVESOCKET_H__AB6D9EB2_1169_4EC5_901F_4655D93FA70E__INCLUDED_)
